package week4;

public class RationalNumber {
    private int numerator, denominator;

    //----------------------------------------------------------------
    // Constructor: Sets up the rational number by ensuring a nonzero
    // denominator and making only th numerator signed.
    //----------------------------------------------------------------
    public RationalNumber(int numer, int demon) {
        if (demon == 0)
            demon = 1;

        // Make the numerator "store" the sign
        if (demon < 0) {
            numer = numer * -1;
            demon = demon * -1;
        }

        numerator = numer;
        denominator = demon;
        reduce();
    }

    //-----------------------------------------------------------------
    // Return the numerator of this rational nuber.
    //-----------------------------------------------------------------
    public int getNumerator() {
        return numerator;
    }

    //-----------------------------------------------------------------
    // Return the denominator of this rational number.
    //-----------------------------------------------------------------
    public int getDenominator() {
        return denominator;
    }

    //-----------------------------------------------------------------
    // Return the reciprocal of this rational number.
    //-----------------------------------------------------------------
    public RationalNumber reciprocal() {
        return new RationalNumber(denominator, numerator);
    }

    //-----------------------------------------------------------------
    // Adds this rational number to the one passed as a parameter.
    // A common denominator is found by multiplying the individual
    // denominators.
    //-----------------------------------------------------------------
    public RationalNumber add(RationalNumber op2) {
        int commonDeniminator = denominator * op2.getDenominator();
        int numerator1 = numerator * op2.getDenominator();
        int numerator2 = op2.getNumerator() * denominator;
        int sum = numerator1 + numerator2;

        return new RationalNumber(sum, commonDeniminator);
    }

    //-----------------------------------------------------------------
    // Subtracts the rational number passed as a parameter from this
    // rational number.
    //-----------------------------------------------------------------
    public RationalNumber subtract(RationalNumber op2) {
        int commonDenominator = denominator * op2.getDenominator();
        int numerator1 = numerator * op2.getDenominator();
        int numerator2 = op2.getNumerator() * denominator;
        int difference = numerator1 - numerator2;

        return new RationalNumber(difference, commonDenominator);
    }

    //-----------------------------------------------------------------
    // Multiplies this rational number by the one passed as a
    // parameter.
    //-----------------------------------------------------------------
    public RationalNumber multiply(RationalNumber op2) {
        int numer = numerator * op2.getNumerator();
        int denom = denominator * op2.getDenominator();

        return new RationalNumber(numer, denom);
    }

    //-----------------------------------------------------------------
    // Divides this rational number by te one passed as a parameter
    // by multiplying by the reciprocal of the second rational.
    //-----------------------------------------------------------------
    public RationalNumber divide(RationalNumber op2) {
        return multiply(op2.reciprocal());
    }

    //-----------------------------------------------------------------
    // Determines if this rational number is equal to the one passed
    // as a parameter. Assumes they are both reduced.
    //-----------------------------------------------------------------
    public boolean isLike(RationalNumber op2) {
        return (numerator == op2.getNumerator() && denominator == op2.getDenominator());
    }

    //-----------------------------------------------------------------
    // Return this rational number as a string.
    //-----------------------------------------------------------------

    @Override
    public String toString() {
        String result;
        if (numerator == 0)
            result = "0";
        else if (denominator == 1)
            result = numerator + "";
        else
            result = numerator + "/" + denominator;
        return result;
    }

    //---------------------------------------------------------------------------------------------
    // Reduces this rational number by dividing both the numerator and the denominator by their
    // greatest common divisor.
    //---------------------------------------------------------------------------------------------
    private void reduce() {
        if (numerator != 0) {
            int common = gcd(Math.abs(numerator), denominator);

            numerator = numerator / common;
            denominator = denominator / common;
        }
    }

    //---------------------------------------------------------------------------------------------
    // Computes and returns the greatest common divisor of the two positive parameters. Uses
    // Euclid's algorithm.
    //---------------------------------------------------------------------------------------------


    private int gcd(int num1, int num2) {
        while (num1 != num2)
            if (num1 > num2)
                num1 = num1 - num2;
            else
                num2 = num2 - num1;

        return num1;
    }

    public int compareTo(RationalNumber op2) {
        double nu1, de1, nu2, de2;
        nu1 = numerator;
        de1 = denominator;
        nu2 = op2.getNumerator();
        de2 = op2.getDenominator();
        double sh1 = nu1 / de1;
        double sh2 = nu2 / de2;
        if (sh1 - sh2 > 0.0001) {
            return 1;
        } else if (sh2 - sh1 > 0.0001) {
            return -1;
        } else {
            return 0;
        }
    }
}


